#include "StdAfx.h"
#include "EditorMgr.h"
#include "AnyEditor.h"
#include "EditorFactory.h"
#include "selecteditor.h"
#include "../GeomUI/MessageGeomUI.h"
#define SafeDelete(pVoid) \
	delete pVoid;\
	pVoid = NULL; 

CEditorMgr::CEditorMgr(CAnyView* pAnyView)
:m_pAnyView(pAnyView),
m_pDefaultEditor(NULL),
m_pEditorBak(NULL),
m_pEditorCur(NULL)
{
	m_pDefaultEditor = new CSelectEditor();
	m_pDefaultEditor->Initialize(m_pAnyView);
}

CEditorMgr::~CEditorMgr(void)
{
	delete m_pDefaultEditor;
	delete m_pEditorBak;
	delete m_pEditorCur;
}
void CEditorMgr::SetDefaultEditor()
{
	CAnyEditor* pEditor = new CSelectEditor();
	pEditor->Initialize(m_pAnyView);
	PushEditor(pEditor);
}
void CEditorMgr::PushEditor(CAnyEditor* pEditor)
{
	ASSERT(pEditor);
	// clear all, if pEditor is a exclusive editor
	// mostly are exclusive editor
	if(pEditor->Type() == ET_EXCLUSIVE)
	{
		SafeDelete(m_pEditorBak);
		SafeDelete(m_pEditorCur);
		m_pEditorCur = pEditor;
		return;
	}
	
	// if pEditor and current are share editors, they can't coexist, so delete current.
	// This is the situation of two view eidtors.
	if(m_pEditorCur && m_pEditorCur->Type()==ET_SHARE && pEditor->Type() == ET_SHARE)
	{
		m_pEditorCur->Abort();
		SafeDelete(m_pEditorCur);
		m_pEditorCur = pEditor;
		return;
	}

	// else, delete old bak and push stack current
	{
		SafeDelete(m_pEditorBak);
		m_pEditorBak = m_pEditorCur;
		m_pEditorCur = pEditor;
	}

}

CAnyEditor* CEditorMgr::PopEditor()
{
	//if(bAutoDelete)
	//{
		SafeDelete(m_pEditorCur);
		m_pEditorCur = m_pEditorBak;
		m_pEditorBak = NULL;
	//}
	if(m_pEditorCur)
		m_pAnyView->SendMessage(WM_GEOM_PROPACTION,GPA_SHOW_SELECTED_PROP,0);
	return m_pEditorCur;
}

CAnyEditor* CEditorMgr::GetTopEidtor()
{
	if(m_pEditorCur)
		return m_pEditorCur;

	return m_pDefaultEditor;
}

UINT CEditorMgr::OnLButtonDown(UINT nFlags, long x, long y)
{
	EditorState es = ES_CONTINUE;
	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{
		EditorState es = pEditor->OnLButtonDown(nFlags, x, y);
		if(es == ES_FINISHED)
		{
			PopEditor();
		}
	}

	return es;
}
UINT CEditorMgr::OnLButtonUp(UINT nFlags, long x, long y)
{
	EditorState es = ES_CONTINUE;
	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{
		es = pEditor->OnLButtonUp(nFlags, x, y);
		if(es == ES_FINISHED)
		{
			PopEditor();
		}
	}

	return es;
}
void CEditorMgr::OnMouseMove(UINT nFlags, long x, long y)
{
	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{
		pEditor->OnMouseMove(nFlags, x, y);
	}
}
UINT CEditorMgr::OnRButtonDown(UINT nFlags, long x, long y)
{
	EditorState es = ES_CONTINUE;
	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{
		es = pEditor->OnRButtonDown(nFlags, x, y);
		if(es == ES_FINISHED)
		{
			PopEditor();
		}
	}

	return es;
}
UINT CEditorMgr::OnRButtonUp(UINT nFlags, long x, long y)
{
	EditorState es = ES_CONTINUE;
	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{
		es = pEditor->OnRButtonUp(nFlags, x, y);
		if(es == ES_FINISHED)
		{
			PopEditor();
		}
	}

	return es;
}
UINT CEditorMgr::OnMouseWheel(UINT nFlags, short zDelta, long x, long y)
{
	EditorState es = ES_CONTINUE;
	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{
		es = pEditor->OnMouseWheel(nFlags,zDelta, x, y);
		if(es == ES_FINISHED)
		{
			PopEditor();
		}
	}

	return es;
}
UINT CEditorMgr::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	EditorState es = ES_CONTINUE;


	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{	
		if(nChar == VK_ESCAPE)
		{
			pEditor->Abort();

			//if(pEditor->Type() == ET_SHARE)
			//{
				PopEditor();
				return ES_FINISHED;
			//}
		}

		es = pEditor->OnKeyDown(nChar, nRepCnt, nFlags);
		if(es == ES_FINISHED)
		{
			PopEditor();
		}
	}

	return es;
}
UINT CEditorMgr::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	return ES_CONTINUE;
}
UINT CEditorMgr::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	EditorState es = ES_CONTINUE;

	CAnyEditor* pEditor = GetTopEidtor();
	if(pEditor)
	{
		es = pEditor->OnKeyUp(nChar, nRepCnt, nFlags);
		if(es == ES_FINISHED)
		{
			PopEditor();
		}
	}

	return es;
}
void CEditorMgr::OnContextMenu(const CMenuContext& contextMenu)
{
};

bool CEditorMgr::StartEditor(const CString& szEditorID, const CEditorData& edData)
{
	CAnyEditor* pEditor = GetEditorFactory().CreateEditor(szEditorID, m_pAnyView);
	if(NULL == pEditor)
		return false;

	pEditor->SetData(edData);
	EditorState es = pEditor->Start();
	if(es == ES_FINISHED)
	{
		delete pEditor;
		pEditor = NULL;
		return false;
	}

	PushEditor(pEditor);

	return true;
}